﻿/**********************************************************************************
* Remarks      :  
* Class Name   :  ExtensionMethods 
* Version      :  v1.0.0.0 
* Author       :  Joey Liang 
* Description  : 
* Created Time :  2013/8/14 22:36:26
* Update Man   :  Joey Liang
* Update Time  :  2013/8/14 22:36:26
************************************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace JoeyLibs.Utility
{
    public static class ExtensionMethods
    {
        #region Common
        ///// <summary>
        ///// 判断两个数组项相等（顺序必须一致）,对数组项使用"Equal方法"校验，
        ///// 如果非CTS类型（即自定义），则应在使用本方法前对Equal方法进行重载
        ///// </summary>
        //public static bool ItemsEqual(this Array array1, Array array2)
        //{
        //    bool equal = false;
        //    if (array1.Length == 0)
        //    {
        //        if (array2 == null || array2.Length == 0)
        //        {
        //            return true;
        //        }
        //    }
        //    else if (array2 == null)
        //    {
        //        return equal;
        //    }

        //    if (array1.Length != array2.Length)
        //    {
        //        return equal;
        //    }

        //    for (int i = 0; i < array1.Length; i++)
        //    {
        //        if (!object.Equals(array1.GetValue(i), array2.GetValue(i)))
        //        {
        //            return equal;
        //        }
        //    }

        //    return true;
        //}

        /// <summary>
        /// 将其他相同集合类型叠加到当前集合
        /// </summary>
        /// <typeparam name="T">集合类型</typeparam>
        /// <param name="collection">原集合</param>
        /// <param name="collectionAdds">需要加的集合</param>
        public static ICollection<T> Add<T>(this ICollection<T> collection, params ICollection<T>[] collectionAdds)
        {
            if (collectionAdds == null || collectionAdds.Length == 0)
            {
                return collection;
            }

            UtilityCommon.ForeachHandle<ICollection<T>>(collectionAdds, cTemp =>
            {
                if (!UtilityCheckData.IsCollectionEmpty<T>(cTemp))
                {
                    UtilityCommon.ForeachHandle<T>(cTemp, t => collection.Add(t));
                }
            });

            return collection;
        }

        /// <summary>
        /// 转为指定类型值
        /// </summary>
        /// <typeparam name="TReturn">转化后的类型</typeparam>
        /// <param name="source">原值</param>
        public static TReturn ChangeType<TReturn>(this object source)
        {
            return UtilityConvert.ChangeType<TReturn, object>(source);
        }
        #endregion

        #region String
        public static string InsertLast(this string source, string str)
        {
            return source.Insert(source.Length, str);
        }

        public static string InsertFirst(this string source, string str)
        {
            return source.Insert(0, str);
        }
        #endregion

        #region Collection
        /// <summary>
        /// 查找集合中满足条件的项
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="source">原集合</param>
        /// <param name="func">条件函数</param>
        public static T FirstOrDefault<T>(this IEnumerable source, Func<T, bool> func)
        {
            foreach (T item in source)
            {
                if (func(item))
                    return item;
            }

            T t = default(T);
            UtilityCommon.ForeachHandle<T>(source, p =>
            {
                if (func(p)) t = p;
            }, null, p => func(p));

            return t;
        }

        /// <summary>
        /// 查找集合中满足条件的项
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="source">原集合</param>
        /// <param name="func">条件函数</param>
        public static IList<T> Where<T>(this IEnumerable source, Func<T, bool> func)
        {
            IList<T> list = new List<T>();
            
            UtilityCommon.ForeachHandle<T>(source, p => 
            { 
                if (func(p)) list.Add(p); 
            });

            return list;
        }

        /// <summary>
        /// 尝试移除指定索引处的 System.Collections.IList 项。
        /// </summary>
        /// <param name="source"></param>
        /// <param name="index"></param>
        /// <returns>返回是否移除成功，如果最大索引小于index将直接返回false</returns>
        public static bool TryRemoveAt(this IList source, int index)
        {
            if (source.Count > 0)
            {
                source.RemoveAt(index);
                return true;
            }

            return false;
        }

        /// <summary>
        /// 判断两个集合里的项相等（顺序必须一致）,对数组项使用"Equal方法"校验，
        /// 如果非CTS类型（即自定义），则应在使用本方法前对Equal方法进行重载
        /// </summary>
        public static bool ItemsEqual(this IList array1, IList array2)
        {
            bool equal = false;
            if (array1.Count == 0)
            {
                if (array2 == null || array2.Count == 0)
                {
                    return true;
                }
            }
            else if (array2 == null)
            {
                return equal;
            }

            if (array1.Count != array2.Count)
            {
                return equal;
            }

            for (int i = 0; i < array1.Count; i++)
            {
                if (!object.Equals(array1[i], array2[i]))
                {
                    return equal;
                }
            }

            return true;
        }

        /// <summary>
        /// 遍历集合执行
        /// </summary>
        /// <typeparam name="T">集合类型参数</typeparam>
        /// <param name="source">源集合</param>
        /// <param name="action">遍历执行的函数</param>
        public static void Foreach<T>(this IEnumerable source, Action<T> action)
        {
            UtilityCommon.ForeachHandle<T>(source, action);
        }
        #endregion

        #region XML
        /// <summary>
        /// 获取XML节点的属性值
        /// </summary>
        /// <param name="node">节点</param>
        /// <param name="attr">属性名</param>
        public static string GetAttribute(this XmlNode node, string attr)
        {
            if (string.IsNullOrEmpty(attr) || node.Attributes[attr] == null)
            {
                return string.Empty;
            }

            return node.Attributes[attr].Value;
        }
        
        /// <summary>
        /// 获取XML节点的属性值
        /// </summary>
        /// <param name="node">节点</param>
        /// <param name="attr">属性名</param>
        public static T GetAttribute<T>(this XmlNode node, string attr)
        {
            if (string.IsNullOrEmpty(attr) || node.Attributes[attr] == null
                || node.Attributes[attr].Value == null)
            {
                return default(T);
            }
            
            return node.Attributes[attr].Value.ChangeType<T>();
        }

        /// <summary>
        /// 查找满足条件的节点
        /// </summary>
        public static XmlNode Find(this XmlNodeList source, Func<XmlNode, bool> func)
        {
            foreach (XmlNode item in source)
            {
                if (func(item))
                    return item;
            }

            return null;
        }

        /// <summary>
        /// 查找满足条件的节点集合
        /// </summary>
        public static ICollection<XmlNode> FindAll(this XmlNodeList source, Func<XmlNode, bool> func)
        {            
            List<XmlNode> list = new List<XmlNode>();
            foreach (XmlNode item in source)
            {
                if (func(item))
                    list.Add(item);
            }

            return list;
        }
        #endregion
    }
}
